package com.github.icloudpay.pay.core.service.refund;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import com.github.icloudpay.pay.core.biz.PayOrderBiz;
import com.github.icloudpay.pay.core.biz.RefundOrderBiz;
import com.github.icloudpay.pay.core.biz.RefundSerialBiz;
import com.github.icloudpay.pay.core.entity.PayOrder;
import com.github.icloudpay.pay.core.entity.RefundOrder;
import com.github.icloudpay.pay.core.entity.RefundSerial;
import com.github.wxiaoqi.security.common.admin.pay.request.CallbackRequest;
import com.github.wxiaoqi.security.common.admin.pay.request.CompleteTradeRequest;
import com.github.wxiaoqi.security.common.msg.ResponseCode;
import com.github.wxiaoqi.security.common.util.EntityUtils;

/**
 * 退款回调
 * @author hexufeng
 */
@EnableAsync
@Service("refundCallbackService")
public class RefundCallbackService {
	
	private static final Logger logger = (Logger) LoggerFactory.getLogger(RefundCallbackService.class);
	
	@Autowired
	private RefundSerialBiz refundSerialBiz;
	@Autowired
	private RefundOrderBiz refundOrderBiz;
	@Autowired
	private PayOrderBiz payOrderBiz;
	@Autowired
	private AmqpTemplate rabbitTemplate;
	
	public void callBack(CallbackRequest callbackRequest){
		logger.info("第三方退款回调开始：请求号{},远程流水号{},交易状态{},",callbackRequest.getRequestNo(),callbackRequest.getRemoteTxJournalNo(),callbackRequest.getStatus());
        
		RefundSerial refundSerial = new RefundSerial();
		refundSerial.setSerialNo(callbackRequest.getRequestNo());
		RefundSerial selectRefundSerial = refundSerialBiz.selectOne(refundSerial);
		if(selectRefundSerial == null){
			logger.error("第三方回调退款流水不存在：回调渠道{},请求号{}",callbackRequest.getPayChannelNo(),callbackRequest.getRequestNo());
			return ;
		}
		
		RefundOrder refundOrder = new RefundOrder();
		refundOrder.setPlatformId(selectRefundSerial.getPlatformId());
		refundOrder.setRefundOrderNo(selectRefundSerial.getRefundOrderNo());
		RefundOrder selsectRefundOrder = refundOrderBiz.selectOne(refundOrder);
		if(selsectRefundOrder == null){
			logger.error("第三方回调退款订单不存在：请求号{}",callbackRequest.getRequestNo());
			return ;
		}
		
        if(selsectRefundOrder.getRefundAmt().compareTo(callbackRequest.getOrderAmt()) != 0){
            logger.error("第三方退款回调交易金额不正确：回调渠道{},请求号{},退款订单退款金额{},第三方退款金额{}",callbackRequest.getPayChannelNo(),callbackRequest.getRequestNo(), selsectRefundOrder.getRefundAmt().toString() ,callbackRequest.getOrderAmt().toString());
            return ;
        }
        
        //已成功，不需要处理
        if("00".equals(selsectRefundOrder.getRefundStatus())){
            logger.info("第三方退款回调已处理，不需要再次处理：回调渠道{},请求号{},回调状态{}",callbackRequest.getPayChannelNo(),callbackRequest.getRequestNo(),selsectRefundOrder.getRefundStatus());
            return ;
        }
        //已失败，不需要处理
        if("01".equals(selsectRefundOrder.getRefundStatus())){
            logger.info("第三方退款回调已处理，不需要再次处理：回调渠道{},请求号{},回调状态{}",callbackRequest.getPayChannelNo(),callbackRequest.getRequestNo(),selsectRefundOrder.getRefundStatus());
            return ;
        }
        
        if("00".equals(callbackRequest.getStatus())){
        	selsectRefundOrder.setRefundStatus("00");//退款成功
        	selectRefundSerial.setRefundStatus("00");//退款成功
        	PayOrder payOrder = new PayOrder();
            payOrder.setPayOrderNo(selsectRefundOrder.getPayOrderNo());
            payOrder.setPlatformId(selsectRefundOrder.getPlatformId());
            PayOrder selectPayOrder = payOrderBiz.selectOne(payOrder);
            BigDecimal addBigDecimal = selectPayOrder.getRefundedAmt().add(callbackRequest.getOrderAmt());
            selectPayOrder.setRefundedAmt(addBigDecimal);
            payOrderBiz.updateById(selectPayOrder);
        }else{
        	selsectRefundOrder.setRefundStatus("01");//退款失败
        	selectRefundSerial.setRefundStatus("01");//退款失败
        }
        refundOrderBiz.updateById(selsectRefundOrder);
        refundSerialBiz.updateById(selectRefundSerial);
        
        //feign异步通知商户退款结果
        CompleteTradeRequest completeTradeRequest = new CompleteTradeRequest();
		completeTradeRequest.setAmount(String.valueOf(selsectRefundOrder.getRefundAmt()));
		completeTradeRequest.setOrderNo(selsectRefundOrder.getRefundOrderNo());
		completeTradeRequest.setPlatformId(selsectRefundOrder.getPlatformId());
		completeTradeRequest.setTradeType("2");//退款
		completeTradeRequest.setPayOrderNo(selsectRefundOrder.getPayOrderNo());
		if("00".equals(callbackRequest.getStatus())){
			completeTradeRequest.setTxStatus("00");
		}else{
			completeTradeRequest.setTxStatus("01");
		}
		
		Map<String, Object> callBackResponse = new HashMap<String, Object>();
		int i = 0;
		do {
			i++;
			if (i > 2) // 如果通知失败，尝试重新通知3次
				break;
			try { // 通知商户
				logger.info("通知商户信息---request{}",EntityUtils.beanToMap(completeTradeRequest));
//				callBackResponse = callBackFeign.callBack(completeTradeRequest);
				String context = EntityUtils.beanToMap(completeTradeRequest).toString();
				this.rabbitTemplate.convertAndSend("topic.payment", context);
			} catch (Exception e) {
				logger.error("通知商户信息失败", e);
			}
		} while (callBackResponse != null && ResponseCode.OK.getCode().equals(callBackResponse.get("code")));
		
		logger.info("退款回调结束");
	}
	
}
